#include "delegate.h"

#include <QPainter>
#include <QPen>
#include <QPalette>
#include <QStyle>

#include "roles.h"


namespace BitWin
{


Delegate::Delegate(QObject* parent):
    QItemDelegate(parent)
{}

void Delegate::paintLeftBound(
    QPainter* painter,
    const QStyleOptionViewItem& option
) const
{
    painter->save();
    
    painter->setPen(
        option.palette.color(QPalette::Normal, QPalette::Dark)
    );
    painter->drawLine(
        option.rect.topLeft(), option.rect.bottomLeft()
    );
    
    painter->restore();
}

void Delegate::paintBitwise(
    QPainter* painter,
    const QStyleOptionViewItem& option,
    const QVariant& data
) const
{
    painter->save();
    
    // Bitwise data representation
    QString bits = data.value<QString>();
    
    // One bit representing rectangle
    qreal w = qreal(option.rect.width()) / bits.size();
    QRectF bit_rect(
        option.rect.left(), option.rect.top(),
        w, option.rect.height()
    );
    
    // Pen objects for drawing bit-separating grid lines and data
    QPen grid_pen(painter->pen());
    QPen text_pen(grid_pen);
    
    // Setup pens
    grid_pen.setColor(
        option.palette.color(QPalette::Normal, QPalette::Mid)
    );
    if (QStyle::State_Selected & option.state)
        text_pen.setColor(
            option.palette.color(QPalette::HighlightedText)
        );
    
    // NB! Least significant index bit is drawn rightmost
    for (int i = bits.size() - 1; i >= 0; --i)
    {
        bit_rect.moveRight(option.rect.right() - i * w);
        painter->setPen(text_pen);
        painter->drawText(bit_rect, Qt::AlignCenter, QString(bits[i]));
        if (!i)
            continue;
        painter->setPen(grid_pen);
        painter->drawLine(bit_rect.topRight(), bit_rect.bottomRight());
    }
    
    painter->restore();
}

void Delegate::paint(
    QPainter* painter,
    const QStyleOptionViewItem& option,
    const QModelIndex& index
) const
{
    QVariant data(index.data(BitwiseDataRole));
    if (
        (data.isValid()) &&
        (data.canConvert<QString>())
    )
    {
        drawBackground(painter, option, index);
        drawFocus(painter, option, option.rect);
        if (index.column())
            paintLeftBound(painter, option);
        paintBitwise(painter, option, data);
    }
    else
        QItemDelegate::paint(painter, option, index);
}


} // BitWin namespace end
